package com.syher.quartz.core.config.quartz.scheduled;

import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;

/**
 * Created by shenyuhang on 2018/2/24.
 */
public class ScheduledManager implements ScheduledCore {

    private static final Logger logger = LoggerFactory.getLogger(ScheduledManager.class);
    private boolean repeat = false;
    Scheduler scheduler;

    protected JobDetail detail;

    private static class Holder {
        private static final ScheduledManager manager = new ScheduledManager();

        public static ScheduledManager instance() {
            return manager;
        }
    }

    public static ScheduledManager builder() {
        return Holder.instance();
    }

    public ScheduledManager setScheduler(Scheduler scheduler) {
        this.scheduler = scheduler;
        return this;
    }

    public ScheduledManager setJobDetail(String name, String group, Class<? extends Job> clazz) {
        detail = JobBuilder.newJob(clazz)
                .withIdentity(name, group)
                .build();
        return this;
    }

    public ScheduledManager setRepeat(boolean repeat) {
        this.repeat = repeat;
        return this;
    }

    public ScheduledManager putDataMap(String key, Object object) {
        detail.getJobDataMap().put(key, object);
        return this;
    }

    public void add(String name, String group, String cron) throws SchedulerException {
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
                .cronSchedule(cron);

        CronTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(name, group)
                .withSchedule(scheduleBuilder)
                .build();

        scheduler.scheduleJob(detail, trigger);
    }

    public void add(String name, String group, Date start, Date end, Integer interval) throws SchedulerException {
        SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder
                .simpleSchedule();
        if (interval != null) {
            scheduleBuilder.withIntervalInSeconds(interval);
        }
        if (repeat) {
            scheduleBuilder.repeatForever();
        }

        TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger()
                .withIdentity(name, group)
                .withSchedule(scheduleBuilder);

        if (start != null) {
            triggerBuilder.startAt(start);
        }

        if (end != null) {
            triggerBuilder.endAt(end);
        }

        scheduler.scheduleJob(detail, triggerBuilder.build());
    }

    public void pause(String name, String group) throws SchedulerException {
        JobKey key = new JobKey(name, group);
        scheduler.pauseJob(key);
    }

    public void resume(String name, String group) throws SchedulerException {
        JobKey key = new JobKey(name, group);
        scheduler.resumeJob(key);
    }

    public void exec(String name, String group) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(name, group);
        scheduler.triggerJob(jobKey);
    }

    public boolean delete(String name, String group) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(name, group);

        TriggerKey triggerKey = scheduler.getTriggerKeys(GroupMatcher.triggerGroupEquals(group))
                .stream().filter(tk -> name.equals(tk.getName())).findFirst().get();

        if (triggerKey != null) {
            //停止触发器
            scheduler.pauseTrigger(triggerKey);
            //移除触发器
            scheduler.unscheduleJob(triggerKey);
        }
        scheduler.interrupt(jobKey);

        return scheduler.deleteJob(jobKey);
    }

    public void modifyTrigger(String name, String group, String cron) throws SchedulerException {
        TriggerKey key = TriggerKey.triggerKey(name, group);

        CronTrigger newTrigger = TriggerBuilder.newTrigger()
                .withIdentity(key)
                .withSchedule(CronScheduleBuilder.cronSchedule(cron))
                .build();

        scheduler.rescheduleJob(key, newTrigger);
    }
}
